home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 2: CDPD 1
/
Almathera Ten on Ten - Disc 2: CDPD 1.iso
/
pd
/
101-125
/
108
/
printpop
/
printpop.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-13
|
19KB
|
577 lines
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* PRINTPOP - A "popup" printer setup program */
/* */
/* by Robbie J Akins, Wellington, NEW ZEALAND */
/* */
/* Version 1.0 */
/* August 1987 */
/* */
/* Thanks for help and inspiration for this program must go to: */
/* */
/* Charles Tyson..................for "Purty" (Fred Fish #66) */
/* The Software Distillery........for "PopCLI" */
/* Rob Peck.......................for the examples in RKM */
/* Willy Langeveld................for "MXGads" (Fred Fish #52) */
/* and especially to Harriet Maybeck Tolly (of TollySoft) and her */
/* article in Amazing Computing about Mutual Exclude gadgets..... */
/* ...that really helped me to stop tearing my hair out! */
/* */
/* To compile: LC:lc1 -iINCLUDE: printpop.c */
/* LC:lc2 -v printpop.c */
/* */
/* To link: Alink with link_printpop */
/* */
/* where "link_printpop" contains: FROM WBC.o,+* */
/* printpop.o */
/* TO PrintPop */
/* LIBRARY lib:lc.lib+lib:amiga.lib */
/* */
/* SPECIAL NOTE: The way this program has been written (the easy way!) */
/* means that either "printpop.o" (generated by the */
/* compiler) must be 'run through' ATOM, or else the */
/* final executable "printpop" must be run through */
/* FIXHUNK (available on Fred Fish #36) for the program */
/* to run correctly (that is, not crash!) on an Amiga */
/* equipped with expansion memory. Sorry. Maybe the */
/* next version of Lattice C will make this a bit easier! */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/tasks.h>
#include <exec/execbase.h>
#include <devices/input.h>
#include <devices/printer.h>
#include <intuition/intuition.h>
#include <visuals.h> /* Visual components of program window */
/*********************** CONSTANTS **********************/
#define F1_KEY 0x50
#define SIGNON "\x1b[33mPRINTPOP\x1b[0m by Robbie J Akins, Wellington NEW ZEALAND\n"
#define DRAFTBUTTON 1
#define NLQBUTTON 2
#define SETTABBUTTON 3
#define CLEARTABBUTTON 4
#define RESETBUTTON 5
#define TENBUTTON 6
#define TWELVEBUTTON 7
#define FIFTEENBUTTON 8
#define PSBUTTON 9
#define ENLARGEDBUTTON 10
#define LMDOWNBUTTON 11
#define LMUPBUTTON 12
#define RMDOWNBUTTON 13
#define RMUPBUTTON 14
/********************** GLOBAL VARIABLES **********************/
struct task *PopUpTask;
struct Interrupt handlerStuff;
ULONG popupsig;
struct MemEntry me[20];
struct IntuitionBase *IntuitionBase = NULL;
struct GfxBase *GfxBase = NULL;
long DOSBase = 0;
struct Window *PopWin;
BOOL success;
int openError;
union printerIO {
struct IOStdReq ios;
struct IODRPReq iodrp;
struct IOPrtCmdReq iopc;
};
union printerIO *request;
struct MsgPort *printerPort;
UBYTE LeftMargBuf[4];
UBYTE RightMargBuf[4];
UBYTE SetMarginsBuffer[12]; /* Buffer for set margins command */
int LeftMargData = 15; /* Initial value of left margin */
int RightMargData = 95; /* Initial value of right margin */
SHORT LeftOffset;
SHORT RightOffset;
/********************** EXTERNAL ROUTINES **********************/
extern struct MsgPort *CreatePort();
extern struct IOStdReq *CreateStdIO();
extern void HandlerInterface();
extern struct task *FindTask();
/************************************************************************
* The handler subroutine - called through the handler stub
*************************************************************************/
struct InputEvent *myhandler(ev, mydata)
struct InputEvent *ev; /* and a pointer to a list of events */
struct MemEntry *mydata[]; /* system will pass me a pointer to my
* own data space. */
{
register struct InputEvent *ep, *laste;
/* scan the list of events to see if "pop-up" key pressed */
for (ep = ev, laste = NULL; ep != NULL; ep = ep->ie_NextEvent)
{
if ((ep->ie_Class == IECLASS_RAWKEY) &&
(ep->ie_Code == F1_KEY) &&
(ep->ie_Qualifier & IEQUALIFIER_LCOMMAND))
{
/* Able to handle this event so take it off the chain */
if (laste == NULL)
ev = ep->ie_NextEvent;
else
laste->ie_NextEvent = ep->ie_NextEvent;
/* Signal to "pop-up" task */
Signal(PopUpTask, popupsig);
}
else
laste = ep;
}
/* pass on the pointer to the event */
return(ev);
}
/************************************************************************
* The main program to do the printpop stuff
*************************************************************************/
void _main()
{
int looping;
ULONG sig,mclass;
LONG GadPos;
struct Gadget *maddress;
struct MsgPort *inputDevPort;
struct IOStdReq *inputRequestBlock;
struct IntuiMessage *mesg;
struct RastPort *ThisRastPort;
PopUpTask = FindTask(0);
sig = Output();
Write(sig, SIGNON, sizeof(SIGNON));
SetTaskPri( PopUpTask, 20);
if ((inputDevPort = CreatePort(0,0)) == NULL) /* for input device */
goto abort0;
if ((inputRequestBlock = CreateStdIO(inputDevPort)) == 0)
goto abort;
if ((sig = AllocSignal(-1)) == -1)
goto abort;
popupsig = 1 << sig;
if ((GfxBase = (struct GfxBase *)
OpenLibrary("graphics.library", 33)) == NULL)
goto abort;
if ((IntuitionBase = (struct IntuitionBase *)
OpenLibrary("intuition.library", 33)) == NULL)
goto abort;
handlerStuff.is_Data = (APTR)&me[0]; /* address of handler data area */
handlerStuff.is_Code = HandlerInterface;/* addr of handler entry point */
handlerStuff.is_Node.ln_Pri = 51; /* set the priority 1 step higher
than Intuition so that handler
enters chain ahead of Intuition*/
if (OpenDevice("input.device",0,inputRequestBlock,0))
goto abort;
inputRequestBlock->io_Command = IND_ADDHANDLER;
inputRequestBlock->io_Data = (APTR)&handlerStuff;
DoIO(inputRequestBlock);
for(;;) /* FOREVER */
{
sig = Wait( popupsig );
if (sig & popupsig)
{
/*=========================================================================*/
WBenchToFront();
if((PopWin=(struct Window *) make_window()) == NULL) /* Open window */
goto CleanUp;
/* Draw Borders and Intuitexts in window */
ThisRastPort = PopWin -> RPort;
DrawBorder(ThisRastPort,&QualityBorder,0,0); /* Draw boxes around gadgets */
PrintIText(ThisRastPort,&QualityText,0,0); /* Write titles above gadgets */
/* Convert values of margins into strings for IntuiTexts */
LeftOffset = IntToText(LeftMargData,LeftMargBuf);
RightOffset = IntToText(RightMargData,RightMargBuf);
LeftMargText.IText = &LeftMargBuf[0];
RightMargText.IText = &RightMargBuf[0];
PrintIText(ThisRastPort,&LeftMargText,LeftOffset,0); /* Print left marg value */
PrintIText(ThisRastPort,&RightMargText,RightOffset,0);/* Print rgt marg value */
/* Set up IDCMP read loop and handle events */
looping = TRUE;
while (looping)
{
WaitPort(PopWin->UserPort);
while((mesg=(struct IntuiMessage *) GetMsg(PopWin->UserPort))!=NULL)
{
mclass = mesg->Class;
maddress = (struct Gadget *)mesg->IAddress;
ReplyMsg(mesg);
if(mclass == CLOSEWINDOW) looping = FALSE;
if(mclass == GADGETDOWN)
{
switch (maddress->GadgetID)
{
case DRAFTBUTTON:
MXGads(PopWin,&DraftGadget,&NLQGadget,
&NULLGadget1,&NULLGadget2);
break;
case NLQBUTTON:
MXGads(PopWin,&NLQGadget,&DraftGadget,
&NULLGadget1,&NULLGadget2);
break;
case SETTABBUTTON:
MXGads(PopWin,&SetTabGadget,&ClearTabGadget,
&NULLGadget1,&NULLGadget2);
break;
case CLEARTABBUTTON:
MXGads(PopWin,&ClearTabGadget,&SetTabGadget,
&NULLGadget1,&NULLGadget2);
break;
case RESETBUTTON:
/* "Ghost" all gadgets on Reset */
GadPos = RemoveGList(PopWin,&RightUpGadget,14L);
ClearTabGadget.Flags ^= GADGDISABLED;
SetTabGadget.Flags ^= GADGDISABLED;
NLQGadget.Flags ^= GADGDISABLED;
DraftGadget.Flags ^= GADGDISABLED;
RightUpGadget.Flags ^= GADGDISABLED;
RightDownGadget.Flags ^= GADGDISABLED;
LeftUpGadget.Flags ^= GADGDISABLED;
LeftDownGadget.Flags ^= GADGDISABLED;
EnlargedGadget.Flags ^= GADGDISABLED;
if((EnlargedGadget.Flags & SELECTED) != SELECTED)
PSGadget.Flags ^= GADGDISABLED;
FifteenGadget.Flags ^= GADGDISABLED;
TwelveGadget.Flags ^= GADGDISABLED;
TenGadget.Flags ^= GADGDISABLED;
AddGList(PopWin,&RightUpGadget,GadPos,14L,(LONG)NULL);
RefreshGList(&RightUpGadget,PopWin,(LONG)NULL,14L);
break;
case TENBUTTON:
MXGads(PopWin,&TenGadget,&TwelveGadget,
&FifteenGadget,&PSGadget);
break;
case TWELVEBUTTON:
MXGads(PopWin,&TwelveGadget,&TenGadget,
&FifteenGadget,&PSGadget);
break;
case FIFTEENBUTTON:
MXGads(PopWin,&FifteenGadget,&TwelveGadget,
&TenGadget,&PSGadget);
break;
case PSBUTTON:
MXGads(PopWin,&PSGadget,&TwelveGadget,
&FifteenGadget,&TenGadget);
break;
case ENLARGEDBUTTON:
/* "Ghost" PS pitch gadget on Enlarged */
/* If PS selected, force to 10 pitch selection*/
if ((PSGadget.Flags & SELECTED) == SELECTED)
MXGads(PopWin,&TenGadget,&TwelveGadget,
&FifteenGadget,&PSGadget);
GadPos = RemoveGList(PopWin,&PSGadget,1L);
PSGadget.Flags ^= GADGDISABLED;
AddGList(PopWin,&PSGadget,GadPos,1L,(LONG)NULL);
RefreshGList(&PSGadget,PopWin,(LONG)NULL,1L);
break;
case LMDOWNBUTTON:
/* Decrement value of left margin */
if(LeftMargData > 1)
{
LeftMargData--;
LeftOffset = IntToText(LeftMargData,LeftMargBuf);
LeftMargText.IText = &LeftMargBuf[0];
PrintIText(ThisRastPort,&BlankText,238,68);
PrintIText(ThisRastPort,&LeftMargText,LeftOffset,0);
}
break;
case LMUPBUTTON:
/* Increment value of left margin */
if(LeftMargData < 998)
{
LeftMargData++;
LeftOffset = IntToText(LeftMargData,LeftMargBuf);
LeftMargText.IText = &LeftMargBuf[0];
PrintIText(ThisRastPort,&BlankText,238,68);
PrintIText(ThisRastPort,&LeftMargText,LeftOffset,0);
}
break;
case RMDOWNBUTTON:
/* Decrement value of right margin */
if(RightMargData > 1)
{
RightMargData--;
RightOffset = IntToText(RightMargData,RightMargBuf);
RightMargText.IText = &RightMargBuf[0];
PrintIText(ThisRastPort,&BlankText,322,68);
PrintIText(ThisRastPort,&RightMargText,RightOffset,0);
}
break;
case RMUPBUTTON:
/* Increment value of right margin */
if(RightMargData < 998)
{
RightMargData++;
RightOffset = IntToText(RightMargData,RightMargBuf);
RightMargText.IText = &RightMargBuf[0];
PrintIText(ThisRastPort,&BlankText,322,68);
PrintIText(ThisRastPort,&RightMargText,RightOffset,0);
}
break;
}
}
}
}
CloseWindow(PopWin); /* Close window on way out */
success = FALSE;
printerPort = (struct MsgPort *)CreatePort("HelloPrinter",0);
if(printerPort == NULL) goto ForgetIt;
request = (union printerIO *)CreateExtIO(printerPort,sizeof(union printerIO));
if(request == NULL) goto ForgetIt;
openError = OpenPrinter(request);
if(openError) goto ForgetIt;
success = TRUE;
/* Now execute appropriate printer commands */
if((ResetGadget.Flags & SELECTED) == SELECTED)
PrintString(request,"\x1b#1"); /* aRIN command */
else
{
if((NLQGadget.Flags & SELECTED) == SELECTED)
PrintString(request,"\x1b[2\x22z"); /* aDEN2 command */
else
PrintString(request,"\x1b[1\x22z"); /* aDEN1 command */
/* First "reset" the printer to normal (10) pich */
PrintString(request,"\x1b[0w"); /* aSHORP0 command */
if((FifteenGadget.Flags & SELECTED) == SELECTED)
PrintString(request,"\x1b[4w"); /* aSHORP4 command */
if((TwelveGadget.Flags & SELECTED) == SELECTED)
PrintString(request,"\x1b[2w"); /*aSHORP2 command */
if((PSGadget.Flags & SELECTED) == SELECTED)
PrintString(request,"\x1b[2p"); /* aPROP2 command */
else
PrintString(request,"\x1b[1p"); /* aPROP1 command */
if((EnlargedGadget.Flags & SELECTED) == SELECTED)
PrintString(request,"\x1b[6w"); /* aSHORP6 command */
else
PrintString(request,"\x1b[5w"); /* aSHORP5 command */
/* Set left & right margins using ESC [ n1 ; n2 s */
strcpy(SetMarginsBuffer,"\x1b[");
strcat(SetMarginsBuffer,LeftMargBuf);
strcat(SetMarginsBuffer,";");
strcat(SetMarginsBuffer,RightMargBuf);
strcat(SetMarginsBuffer,"s");
PrintString(request,SetMarginsBuffer);
if((SetTabGadget.Flags & SELECTED) == SELECTED)
PrintString(request,"\x1b#5"); /* aTBSALL command */
else
PrintString(request,"\x1b#4");/* aTBCALL command */
}
PrintString(request,"\x0d"); /* Terminating C/R required by some printers */
goto CleanUp; /* Exit gracefully */
ForgetIt:
Apologise("Sorry, but unable to send the",
"control codes that you requested",
"to the printer. Maybe in use?");
CleanUp:
if(success) ClosePrinter(request);
if(printerPort) DeletePort(printerPort);
if(request) DeleteExtIO(request);
/*=========================================================================*/
}
} /* END OF FOREVER LOOP */
abort:
if (IntuitionBase != NULL)
CloseLibrary(IntuitionBase);
if (GfxBase != NULL)
CloseLibrary(GfxBase);
DeletePort(inputDevPort);
abort0:
XCEXIT(-1);
}
/************************************************************************
* Function to open window
*************************************************************************/
make_window()
{
struct NewWindow NewWindow;
NewWindow.LeftEdge=0;
NewWindow.TopEdge=0;
NewWindow.Width=402;
NewWindow.Height=103;
NewWindow.DetailPen=0;
NewWindow.BlockPen=1;
NewWindow.IDCMPFlags= CLOSEWINDOW | GADGETDOWN;
NewWindow.Flags= ACTIVATE | WINDOWDRAG | WINDOWDEPTH |
WINDOWCLOSE | NOCAREREFRESH | GIMMEZEROZERO;
NewWindow.FirstGadget=&RightUpGadget;
NewWindow.CheckMark=NULL;
NewWindow.Title="PRINTPOP - Printer Setup Utility";
NewWindow.Screen=NULL;
NewWindow.BitMap=NULL;
NewWindow.MinWidth=0;
NewWindow.MinHeight=0;
NewWindow.MaxWidth=0;
NewWindow.MaxHeight=0;
NewWindow.Type=WBENCHSCREEN;
return(OpenWindow(&NewWindow));
}
/********************************************************************
* This routine fakes mutual-exclude of four gadgets
********************************************************************/
MXGads(win,gad1,gad2,gad3,gad4)
struct Window *win;
struct Gadget *gad1,*gad2,*gad3,*gad4;
{
LONG GadNumber1,GadNumber2,GadNumber3,GadNumber4;
GadNumber1 = RemoveGList(win,gad1,1L);
GadNumber2 = RemoveGList(win,gad2,1L);
GadNumber3 = RemoveGList(win,gad3,1L);
GadNumber4 = RemoveGList(win,gad4,1L);
gad1->Flags |= SELECTED; /* FORCE TO BE SELECTED! */
if((gad2->Flags & SELECTED) == SELECTED) (gad2->Flags ^= SELECTED);
if((gad3->Flags & SELECTED) == SELECTED) (gad3->Flags ^= SELECTED);
if((gad4->Flags & SELECTED) == SELECTED) (gad4->Flags ^= SELECTED);
AddGList(win,gad4,GadNumber4,1L,(LONG)NULL);
RefreshGList(gad4,win,(LONG)NULL,1L);
AddGList(win,gad3,GadNumber3,1L,(LONG)NULL);
RefreshGList(gad3,win,(LONG)NULL,1L);
AddGList(win,gad2,GadNumber2,1L,(LONG)NULL);
RefreshGList(gad2,win,(LONG)NULL,1L);
AddGList(win,gad1,GadNumber1,1L,(LONG)NULL);
RefreshGList(gad1,win,(LONG)NULL,1L);
}
/************************************************************************
* Printersupport routines from 1.1 Rom Kernel manual
*************************************************************************/
/* OPEN THE PRINTER */
int
OpenPrinter(request)
union printerIO *request;
{
return(OpenDevice("printer.device",0,request,0));
}
/* CLOSE THE PRINTER */
int
ClosePrinter(request)
union printerIO *request;
{
CloseDevice(request);
return(0);
}
/* SEND NULL TERMINATED STRING TO PRINTER */
int
PrintString(request,string)
union printerIO *request;
char *string;
{
request->ios.io_Command = CMD_WRITE;
request->ios.io_Data = (APTR)string;
request->ios.io_Length = -1;
return(DoIO(request));
}
/************************************************************************
* Raise an autorequester with (up to) three lines of text
*************************************************************************/
Apologise (line1, line2, line3)
UBYTE *line1, *line2, *line3;
{
Sorry[0].IText = line1;
Sorry[1].IText = line2;
Sorry[2].IText = line3;
AutoRequest (NULL, &Sorry, NULL, &Proceed, 0, 0, 300, 66);
}
/************************************************************************
* Convert margin value into text for IntuiText
* (returns value to displace text string by for "good" appearance)
*************************************************************************/
IntToText(n,string)
int n;
UBYTE *string;
{
int displace; /* Amount to displace display of text by */
string[0] = n/100 +'0';
if (string[0] == '0')
{
string[0] = (n%100)/10 + '0';
if (string[0] == '0')
{
string[0] = (n%100)%10 + '0';
string[1] = '\0';
displace = 8;
}
else
{
string[1] = (n%100)%10 + '0';
string[2] = '\0';
displace = 4;
}
}
else
{
string[1] = (n%100)/10 + '0';
string[2] = (n%100)%10 + '0';
string[3] = '\0';
displace = 0;
}
return(displace);
}